<?php


namespace wchat\common;


class Decode
{

	private string $sessionKey;
	private string $iv;
	private string $encryptedData;
	private string $appId;


	private int $OK = 0;
	private int $IllegalAesKey = -41001;
	private int $IllegalIv = -41002;
	private int $IllegalBuffer = -41003;
	private int $DecodeBase64Error = -41004;

	/**
	 * @return string
	 */
	public function getSessionKey(): string
	{
		return $this->sessionKey;
	}

	/**
	 * @param string $sessionKey
	 */
	public function setSessionKey(string $sessionKey): void
	{
		$this->sessionKey = $sessionKey;
	}

	/**
	 * @return string
	 */
	public function getIv(): string
	{
		return $this->iv;
	}

	/**
	 * @param string $iv
	 */
	public function setIv(string $iv): void
	{
		$this->iv = $iv;
	}

	/**
	 * @return string
	 */
	public function getEncryptedData(): string
	{
		return $this->encryptedData;
	}

	/**
	 * @param string $encryptedData
	 */
	public function setEncryptedData(string $encryptedData): void
	{
		$this->encryptedData = $encryptedData;
	}

	/**
	 * @return string
	 */
	public function getAppId(): string
	{
		return $this->appId;
	}

	/**
	 * @param string $appId
	 */
	public function setAppId(string $appId): void
	{
		$this->appId = $appId;
	}


	/**
	 * @param $asArray
	 * @return array|mixed
	 * @throws \Exception
	 */
	public function decode($asArray): object|array
	{
		if (strlen($this->sessionKey) != 24) {
			throw new \Exception('encodingAesKey 非法', $this->IllegalAesKey);
		}

		$aesKey = base64_decode($this->sessionKey);
		if (strlen($this->iv) != 24) {
			throw new \Exception('base64解密失败', $this->IllegalIv);
		}

		$aesIV = base64_decode($this->iv);
		$aesCipher = base64_decode($this->encryptedData);
		$result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, OPENSSL_RAW_DATA, $aesIV);
		if ($result === false) {
			throw new \Exception('aes 解密失败', $this->IllegalBuffer);
		}

		$dataObj = json_decode($result);
		if ($dataObj->watermark->appid != $this->appId) {
			throw new \Exception('aes 解密失败', $this->IllegalBuffer);
		}
		return $asArray ? get_object_vars($dataObj) : $dataObj;
	}

}
